package com.lsh.order.controller;

import com.lsh.common.util.ResultObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ：LiuShihao
 * @date ：Created in 2021/7/28 8:09 下午
 * @desc ：
 */
@RestController
public class OrderRestTemplateController {

    @Autowired
    RestTemplate restTemplate;

    /**
     * getForObject 和 getForEntity 的差异主要体现在返回值上，
     * getForObject 的返回值就是服务提供者返回的数据，
     * 使用 getForObject 无法获取到响应头。
     * @return
     */
    @GetMapping("/OrderGetForAccount")
    public ResultObject get(){
        /**
         *
         * GET请求带参数 http://localhost:9000/account/get?name={1}&age={2}
         * getForEntity 方法:第一个参数是 url ，url 中有一个占位符 {1} ,如果有多个占位符分别用 {2} 、 {3} … 去表示，第二个参数是接口返回的数据类型，最后是一个可变长度的参数，用来给占位符填值。
         *
         */
        //第一种 使用{1}占位符   参数按顺序进行传参
        String url1 = "http://localhost:9000/account/get?name={1}&age={2}";
        //第二种 使用{name}占位符  使用Map进行传参 key为name
        String url2 = "http://localhost:9000/account/get?name={name}&age={age}";
        String name = "zhangsan";
        int age = 20;
//        String forObject = restTemplate.getForObject(url, String.class,name,age);
        HashMap<String, Object> map = new HashMap<>();
        map.put("name",name);
        map.put("age",age);
//        String forObject = restTemplate.getForObject(url, String.class,map);
        //第三种 URI，参数直接拼接  http://localhost:9000/account/get?name=zhangsan&age=18
        URI uri = URI.create("http://localhost:9000/account/get?name=zhangsan&age=18");
//        String forObject = restTemplate.getForObject(uri, String.class);

        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url1, String.class, "zs", 19);
        System.out.println("body : "+responseEntity.getBody());
        System.out.println("statusCode : "+responseEntity.getStatusCode());
        System.out.println("statusCodeValue : "+responseEntity.getStatusCodeValue());
        System.out.println("Headers : "+responseEntity.getHeaders());

        return new ResultObject(true,0000,"restTemplate.getForObject()",responseEntity.getBody());


    }

    /**
     * 在 POST 请求中，参数的传递可以是 key/value 的形式，也可以是 JSON 数据
     *
     * @return
     */
    @GetMapping("/OrderPostForAccount")
    public ResultObject post(){
        /**
         * postForEntity:
         * 1.传递 key/value 形式的参数
         *  postForEntity 方法第一个参数是请求地址，
         *  第二个参数 map 对象中存放着请求参数 key/value，
         *  第三个参数则是返回的数据类型。当然这里的第一个参数
         *  url 地址也可以换成一个 Uri 对象，效果是一样的。这种方式传递的参数是以 key/value 形式传递的
         */
        String url1 = "http://localhost:9000/account/postKeyValue";
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("name","zhangsan");
        map.add("age",20);
//        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url1, map, String.class);

        // 在 post 请求中，也可以按照 get 请求的方式去传递 key/value 形式的参数，传递方式和 get 请求的传参方式基本一致

        String url2 = "http://localhost:9000/account/postKeyValue?name={1}&age={2}";
        String name = "zhangsan";
        //可以用包装类Integer来避免这个错误 Optional int parameter 'age' is present but cannot be translated into a null
        //在springmvc接受参数的时候，尽量不要使用基本数据类型
        Integer age = 20;

//        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url2, null, String.class, name, age);


        String url3 = "http://localhost:9000/account/postJson";
        HashMap<String, Object> map1 = new HashMap<>();
        map1.put("name","lisi");
        map1.put("age",22);
        //唯一的区别就是第二个参数的类型不同，这个参数如果是一个 MultiValueMap 的实例，则以 key/value 的形式发送，如果是一个普通对象，则会被转成 json 发送
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url3, map1, String.class);

        System.out.println("body : "+responseEntity.getBody());
        System.out.println("statusCode : "+responseEntity.getStatusCode());
        System.out.println("statusCodeValue : "+responseEntity.getStatusCodeValue());
        System.out.println("Headers : "+responseEntity.getHeaders());
        return new ResultObject(true,0000,"restTemplate.getForObject()",responseEntity.getBody());

    }

    /**
     * 这三个重载的方法其参数其实和 POST 是一样的，
     * 可以用 key/value 的形式传参，也可以用 JSON 的形式传参，无论哪种方式，都是没有返回值的
     * @return
     */
    @GetMapping("/OrderPutForAccount")
    public ResultObject put(){
        String url1= "http://localhost:9000/account/putKeyValue";
        String url2= "http://localhost:9000/account/putJson";
        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("name","lisi");
        multiValueMap.add("age",21);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("name","zs");
        hashMap.put("age",12);
        restTemplate.put(url1,multiValueMap);
        restTemplate.put(url2,hashMap);
        return new ResultObject(true,0000,"restTemplate.put");

    }

    /**
     * 参数：
     * 一个的参数在路径中，
     * 另一个的参数以 key/value 的形式传递
     * @return
     */
    @GetMapping("/OrderDelForAccount")
    public ResultObject delete(){

        String url1 = "http://localhost:9000/account/del?name={name}&age={age}";
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("name","zs");
        hashMap.put("age",12);
        restTemplate.delete(url1,hashMap);


        String url2 = "http://localhost:9000/account/del/{id}";
        HashMap<String, Object> hashMap2 = new HashMap<>();
        hashMap2.put("id",11);
        restTemplate.delete(url2,hashMap2);


        URI uri = URI.create("http://localhost:9000/account/del/99");
        restTemplate.delete(uri);

        return new ResultObject(true,0000,"restTemplate.delete");

    }

    @GetMapping("/OrderExchangeForAccount")
    public ResultObject exchande(){

        String name = "zhangsan";
        Integer age = 23;

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("name",name);
        hashMap.put("age",age);

        MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
        multiValueMap.add("name",name);
        multiValueMap.add("age",age);

        //构造请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add("username","ZhangSan");

        //  GET
        String url1 = "http://localhost:9000/account/get?name={1}&age={2}";
        //构造请求体   第一个参数实际上就相当于 POST/PUT 请求中的第二个参数；第二个参数是请求头
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(null,headers);
        ResponseEntity<String> exchange = restTemplate.exchange(url1, HttpMethod.GET, httpEntity, String.class,name,age);

         // POST 请求 key/value格式
        String url2 = "http://localhost:9000/account/postKeyValue";
        HttpEntity<MultiValueMap<String, Object>> httpEntity2 = new HttpEntity<>(multiValueMap,headers);
        ResponseEntity<String> exchange2 = restTemplate.exchange(url2, HttpMethod.POST, httpEntity2, String.class);

         // POST 请求 JSON格式
        String url3 = "http://localhost:9000/account/postJson";
        HttpEntity<Map<String, Object>> httpEntity3 = new HttpEntity<>(hashMap,headers);
        ResponseEntity<String> exchange3 = restTemplate.exchange(url3, HttpMethod.POST, httpEntity3, String.class);

        //  PUT key/value
        String url4= "http://localhost:9000/account/putKeyValue";
        ResponseEntity<String> exchange4 = restTemplate.exchange(url4, HttpMethod.PUT, httpEntity2,String.class);

        //  PUT  JSON
        String url5= "http://localhost:9000/account/putJson";
        ResponseEntity<String> exchange5 = restTemplate.exchange(url5, HttpMethod.PUT, httpEntity3,String.class);

        //DELETE
        String url6 = "http://localhost:9000/account/del?name={name}&age={age}";
        HttpEntity<Map<String, Object>> httpEntity6 = new HttpEntity<>(null,headers);
        ResponseEntity<String> exchange6 = restTemplate.exchange(url6, HttpMethod.DELETE, httpEntity3, String.class,hashMap);




        System.out.println("body : "+exchange.getBody());
        System.out.println("statusCode : "+exchange.getStatusCode());
        System.out.println("statusCodeValue : "+exchange.getStatusCodeValue());
        System.out.println("Headers : "+exchange.getHeaders());

        return new ResultObject(true,0000,"restTemplate.exchange",exchange.getBody());

    }







}
